#ifndef IO_SERVICE_POOL_H
#define IO_SERVICE_POOL_H

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <list>
#include <unistd.h>

using namespace boost::asio;


#define CPUS sysconf(_SC_NPROCESSORS_ONLN)

class io_service_pool
{
public:

    typedef boost::shared_ptr<io_service> io_service_ptr;
    typedef boost::shared_ptr<io_service::work> work_ptr;

    io_service_pool()
    {
        std::cout << "--init--" << std::endl;
        init();
        std::cout << "--init--" << std::endl;
    }

    ~io_service_pool()
    {

    }

    void start()
    {
        std::cout << "--start--" << std::endl;
        if (!m_threads.size()) {
            for (std::list<io_service_ptr>::iterator ite = m_io_services.begin();
                 ite != m_io_services.end(); ++ite) {
                m_threads.create_thread(boost::bind(&io_service::run, (*ite).get()));
            }
            std::cout << "--join--" << std::endl;
            m_threads.join_all();
            std::cout << "--join--" << std::endl;
        }
        std::cout << "--start--" << std::endl;
    }

    void stop()
    {
        for (std::list<io_service_ptr>::iterator ite = m_io_services.begin();
             ite != m_io_services.end(); ++ite) {
            (*ite)->post(boost::bind(&io_service::stop, (*ite).get()));
        }
        m_works.clear();
    }

private:
    void init(int cpu = CPUS)
    {
        for (int i = 0; i < cpu; ++i) {
            m_io_services.push_back(io_service_ptr(new io_service));
            m_works.push_back(work_ptr(new io_service::work(*m_io_services.back())));
        }
    }

    std::list<io_service_ptr> m_io_services;
    std::list<work_ptr> m_works;
    boost::thread_group m_threads;


};

int main()
{

    io_service_pool pool;

    pool.start();

    std::cout << "--start--!" << std::endl;


    pool.stop();

    return 0;

}

#endif // IO_SERVICE_POOL_H
